This file contains statistics and figures from the paper, “Molecular,
Cellular, and Developmental Organization of the Mouse Vomeronasal organ
at Single Cell Resolution” by Max Hills Jr., Limei Ma, Ai Fang, Thelma
Chiremba, Seth Malloy, Allison Scott, Anoja Perera, and C. Ron Yu.
The paper can be found here:
Molecular,
Cellular, and Developmental Organization of the Mouse Vomeronasal organ
at Single Cell Resolution
Single cell transcriptomic profile of
the whole vomeronasal organ
What cell types, in what quantities, do we find in the whole
VNO?
[1] "There are 34519 cells in the whole VNO dataset."
| V1R_mVSN |
13201 |
| V2R_mVSN |
4366 |
| SUS |
3889 |
| sVSN |
2601 |
| V1R_iVSN |
1794 |
| V2R_iVSN |
1582 |
| Microglia |
1366 |
| Immune_Fpr |
1222 |
| LP |
1072 |
| HBC |
912 |
| INP |
528 |
| Microglia_rp |
455 |
| mOSN |
430 |
| T_cells |
313 |
| Endothelial |
251 |
| OEC |
220 |
| GBC |
218 |
| MV |
99 |
2D PCA of Clusters

2D UMAP Clusters

UMAP visualization of integrated cell-type clusters for whole-VNO
single-cell RNA-seq
In two-dimensional UMAP space, 18 cell clusters can be clearly
identified.

Cell-type marker-gene normalized expression across the cell
clusters
These clusters were curated using known cell markers (Fig. 1b).

UMAP of cell-type clusters split by age

UMAP of cell-type clusters split by sex

Spatial location of individual VNO cells color-coded according to
cell type prediction based on the spatial transcriptomic analysis

Location of cell belonging to HBC, GBC, INP, and LP cell types,
respectively. Heat indicates confidence of predicted values

LS0tCnRpdGxlOiAiVk5PIEF0bGFzIEZpZ3VyZSAxIgphdXRob3I6ICJNYXggSGlsbHMiCmRhdGU6ICJgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVkICVCLCAlWScpYCIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKPlRoaXMgZmlsZSBjb250YWlucyBzdGF0aXN0aWNzIGFuZCBmaWd1cmVzIGZyb20gdGhlIHBhcGVyLCAiTW9sZWN1bGFyLCBDZWxsdWxhciwgYW5kIERldmVsb3BtZW50YWwgT3JnYW5pemF0aW9uIG9mIHRoZSBNb3VzZSBWb21lcm9uYXNhbCBvcmdhbiBhdCBTaW5nbGUgQ2VsbCBSZXNvbHV0aW9uIiBieSBNYXggSGlsbHMgSnIuLCBMaW1laSBNYSwgQWkgRmFuZywgVGhlbG1hIENoaXJlbWJhLCBTZXRoIE1hbGxveSwgQWxsaXNvbiBTY290dCwgQW5vamEgUGVyZXJhLCBhbmQgQy4gUm9uIFl1LiAgICAKClRoZSBwYXBlciBjYW4gYmUgZm91bmQgaGVyZTogIAoKW01vbGVjdWxhciwgQ2VsbHVsYXIsIGFuZCBEZXZlbG9wbWVudGFsIE9yZ2FuaXphdGlvbiBvZiB0aGUgTW91c2UgVm9tZXJvbmFzYWwgb3JnYW4gYXQgU2luZ2xlIENlbGwgUmVzb2x1dGlvbl0oaHR0cHM6Ly9lbGlmZXNjaWVuY2VzLm9yZy9yZXZpZXdlZC1wcmVwcmludHMvOTczNTYjdGFiLWNvbnRlbnQpCgoqKiogIAoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CgojIFItTWFya2Rvd24gR2xvYmFsIFNldHRpbmdzICAKCiMgU2V0LXVwIGEgZGVmYXVsdCBpbWFnZSBzaXplIG9mIDEwIFggMTAgaW5jaGVzLiBTdXBwcmVzcyB3YXJuaW5nCiMgYW5kIGVycm9yIG1lc3NhZ2VzLiBIaWRlIGNvZGUuCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCBjb21tZW50PSIiLAogICAgICAgICAgICAgICAgICAgICAgZXJyb3I9RkFMU0UsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD0xMCwgY2FjaGU9RkFMU0UpCgpgYGAKCmBgYHtyIGxpYnJhcmllcywgaW5jbHVkZT1GQUxTRX0KCiMgTGlicmFyeSBMb2FkaW5nICAKCnN1cHByZXNzUGFja2FnZVN0YXJ0dXBNZXNzYWdlcyh7CiAgbGlicmFyeShraXQpOyBsaWJyYXJ5KHRpZHl2ZXJzZSk7IGxpYnJhcnkoc3RyaW5ncik7IGxpYnJhcnkocGxvdDNEKSAKICBsaWJyYXJ5KGdncGxvdDIpOyBsaWJyYXJ5KGRhdGEudGFibGUpOyBsaWJyYXJ5KG9yZy5NbS5lZy5kYikKICBsaWJyYXJ5KGRwbHlyKTsgbGlicmFyeShTZXVyYXQpOyBsaWJyYXJ5KERCSSk7IGxpYnJhcnkoY293cGxvdCkKICBsaWJyYXJ5KE1hdHJpeCk7IGxpYnJhcnkoZ2xtR2FtUG9pKTsgbGlicmFyeShjaXJjbGl6ZSkKICBsaWJyYXJ5KHRpYmJsZSk7IGxpYnJhcnkoZ2dwdWJyKTsgbGlicmFyeShzdmdsaXRlKTsgbGlicmFyeShnZ3NpZ25pZikKICBsaWJyYXJ5KHN0YXRzKTsgbGlicmFyeSh2ZWdhbik7IGxpYnJhcnkoc2NhbGVzKTsgbGlicmFyeShjYXJldCkKICBsaWJyYXJ5KHBhdGNod29yayk7IGxpYnJhcnkocGxvdGx5KTsgbGlicmFyeShnZW9tdGV4dHBhdGgpCiAgbGlicmFyeShvcGVueGxzeCk7IGxpYnJhcnkoZ3JpZEV4dHJhKTsgbGlicmFyeShnZ3JlcGVsKQogIGxpYnJhcnkoR2VuZU92ZXJsYXApOyBsaWJyYXJ5KGJpb21hUnQpOyBsaWJyYXJ5KGdncG9pbnRkZW5zaXR5KQogIGxpYnJhcnkoc2xpbmdzaG90KTsgbGlicmFyeSh0cmFkZVNlcSk7IGxpYnJhcnkoU2luZ2xlQ2VsbEV4cGVyaW1lbnQpCiAgbGlicmFyeSh2aXJpZGlzKTsgbGlicmFyeShVcFNldFIpOyBsaWJyYXJ5KHBoZWF0bWFwKTsgbGlicmFyeShtc2lnZGJyKQogIGxpYnJhcnkoZmdzZWEpOyBsaWJyYXJ5KGdyaWQpOyBsaWJyYXJ5KElEUG1pc2MpOyBsaWJyYXJ5KE1BU1MpCiAgbGlicmFyeShSbWlzYyk7IGxpYnJhcnkoZ2dwbG90aWZ5KTsgbGlicmFyeShnZ3BtaXNjKTsgbGlicmFyeShzY2FsZXMpCiAgbGlicmFyeShoZWF0bWFwbHkpOyBsaWJyYXJ5KGRlbmRleHRlbmQpCn0pCgpgYGAKCmBgYHtyfQoKIyBHbG9iYWwgVmFyaWFibGVzCgojIFRoZSBob21lIGRpcmVjdG9yeQpob21lX2RpciA8LSAiL2wvWXUvWXVMYWIvQmlvaW5mb3JtYXRpY3MvcHJvamVjdHMvbWhoL3NjX1ZOTy8iCiMgRGlyZWN0b3J5IGZvciBzdG9yaW5nIGRhdGEgb2JqZWN0cyBhdCBjcnVjaWFsIHN0YWdlcwpvYmplY3RfZGlyIDwtIHBhc3RlMChob21lX2RpciwiZmluYWwuc2V1Lm9ianMvIikKIyBEaXJlY3RvcnkgZm9yIGltYWdlcyBmcm9tIHRoZSBmaW5hbCBhbmFseXNpcwppbWFnZV9kaXIgPC0gcGFzdGUwKGhvbWVfZGlyLCJmaW5hbF9pbWFnZXMvIikKYWRvYmVfaW1hZ2VzIDwtIHBhc3RlMChpbWFnZV9kaXIsICJhZG9iZV9pbGx1c3RyYXRvcl9zdmdfZmlsZXMvIikKIyBEaXJlY3RvcnkgZm9yIGltYWdlcyBmb3IgdGhlIGZpbmFsIHBhcGVyCmNsdXN0cmVlX2RpciA8LSBwYXN0ZTAoaW1hZ2VfZGlyLCJjbHVzdHJlZS8iKQojIEEgZGlyZWN0b3J5IGZvciBUcmFkZVNlcSBmaXRHQU0gb3V0cHV0CmZpdEdBTV9kaXIgPC0gcGFzdGUwKG9iamVjdF9kaXIsICJmaXRHQU0vIikKbW9lX2RpciA8LSAiL2wvWXUvWXVMYWIvQmlvaW5mb3JtYXRpY3MvcHJvamVjdHMvbWhoL21vbG5nXzI0MDdfMjQ1My9SX29iai8iCgojIE9QRU4gYGBgdm5vLnNldS5pbnRlZ3JhdGVkYGBgCmxvYWQoZmlsZSA9IHBhc3RlMChvYmplY3RfZGlyLCJ2bm8uaW50ZWdyYXRlZC5wb3N0Q2VsbElEIikpCiNMb2FkIE5ldXJvbmFsIExpbmVhZ2UgU2V1cmF0IE9iamVjdCAgCmxvYWQoZmlsZSA9IHBhc3RlMChvYmplY3RfZGlyLCJuZXVyb24uaW50ZWdyYXRlZC5wb3N0Q2VsbElEIikpCgojIFJlbmFtZSB1bmtub3duX21WU04gdG8gc1ZTTgpsZXZlbHModm5vLnNldS5pbnRlZ3JhdGVkQGFjdGl2ZS5pZGVudClbbGV2ZWxzKHZuby5zZXUuaW50ZWdyYXRlZEBhY3RpdmUuaWRlbnQpPT0idW5rbm93bl9tVlNOIl0gPC0gInNWU04iCmxldmVscyhuZXVyb24uaW50ZWdyYXRlZEBhY3RpdmUuaWRlbnQpW2xldmVscyhuZXVyb24uaW50ZWdyYXRlZEBhY3RpdmUuaWRlbnQpPT0idW5rbm93bl9tVlNOIl0gPC0gInNWU04iCmxldmVscyh2bm8uc2V1LmludGVncmF0ZWQkY2VsbF90eXBlKVtsZXZlbHModm5vLnNldS5pbnRlZ3JhdGVkJGNlbGxfdHlwZSk9PSJ1bmtub3duX21WU04iXSA8LSAic1ZTTiIKbGV2ZWxzKG5ldXJvbi5pbnRlZ3JhdGVkJGNlbGxfdHlwZSlbbGV2ZWxzKG5ldXJvbi5pbnRlZ3JhdGVkJGNlbGxfdHlwZSk9PSJ1bmtub3duX21WU04iXSA8LSAic1ZTTiIKCiMgR2V0IGNvbG9yIHNjaGVtZSBmb3IgdGhlIHdob2xlIHZubyBkYXRhc2V0CnZuby5jZWxsX3R5cGUuY29sb3JzIDwtIGh1ZV9wYWwoKShsZW5ndGgobGV2ZWxzKHZuby5zZXUuaW50ZWdyYXRlZEBhY3RpdmUuaWRlbnQpKSkKbmFtZXModm5vLmNlbGxfdHlwZS5jb2xvcnMpIDwtIGxldmVscyh2bm8uc2V1LmludGVncmF0ZWRAYWN0aXZlLmlkZW50KQoKIyBLZWVwIG5ldXJvbiBkYXRhc2V0IGNvbG9yIHNjaGVtZSBjb25zaXN0ZW50IHdpdGggdGhlIHdob2xlIHZubyBjb2xvciBzY2hlbWUsIHdoZXJlIHBvc3NpYmxlICAKbmV1cm9uLmNlbGxfdHlwZS5jb2xvcnMgPC0gdm5vLmNlbGxfdHlwZS5jb2xvcnNbYygiVjFSX21WU04iLCJWMlJfbVZTTiIsIm1PU04iLCJzVlNOIiwiVjFSX2lWU04iLCJWMlJfaVZTTiIsIkdCQyIpXQpuZXVyb24uY2VsbF90eXBlLmNvbG9ycyA8LSBzZXROYW1lcyhjKG5ldXJvbi5jZWxsX3R5cGUuY29sb3JzLCIjMDBCMEY2IiwiIzk1OTBGRiIsIiNFNzZCRjMiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYyhuYW1lcyhuZXVyb24uY2VsbF90eXBlLmNvbG9ycyksImlPU04iLCJsYXRlX0lOUCIsImVhcmx5X0lOUCIpKQoKbWF0dXJlLm5ldXJvbnMgPC0gc3Vic2V0KG5ldXJvbi5pbnRlZ3JhdGVkLGlkZW50cz1jKCJWMVJfbVZTTiIsIlYyUl9tVlNOIiwibU9TTiIsInNWU04iKSkKbWF0dXJlLmNlbGxfdHlwZS5jb2xvcnMgPC0gbmV1cm9uLmNlbGxfdHlwZS5jb2xvcnNbYygiVjFSX21WU04iLCJWMlJfbVZTTiIsIm1PU04iLCJzVlNOIildCgpnbG9iYWwudmFycyA8LSBjKGxzKCksImdsb2JhbC52YXJzIikKCmBgYAoKKioqICAKCiMgU2luZ2xlIGNlbGwgdHJhbnNjcmlwdG9taWMgcHJvZmlsZSBvZiB0aGUgd2hvbGUgdm9tZXJvbmFzYWwgb3JnYW4gey50YWJzZXQgLnRhYnNldC1waWxsc30gIAoKIyMgV2hhdCBjZWxsIHR5cGVzLCBpbiB3aGF0IHF1YW50aXRpZXMsIGRvIHdlIGZpbmQgaW4gdGhlIHdob2xlIFZOTz8gIAoKYGBge3J9CgpwcmludChwYXN0ZSgiVGhlcmUgYXJlIixkaW0odm5vLnNldS5pbnRlZ3JhdGVkKVsyXSwiY2VsbHMgaW4gdGhlIHdob2xlIFZOTyBkYXRhc2V0LiIpKQprbml0cjo6a2FibGUoc29ydCh0YWJsZSh2bm8uc2V1LmludGVncmF0ZWQkY2VsbF90eXBlKSwgZGVjcmVhc2luZyA9IFRSVUUpLGNvbC5uYW1lcz1jKCJjZWxsIHR5cGUiLCJuQ2VsbHMiKSkKCmBgYAoKIyMgMkQgUENBIG9mIENsdXN0ZXJzICAKCmBgYHtyfQoKdm5vLnNldS5pbnRlZ3JhdGVkJHNldXJhdF9jbHVzdGVycyA8LSBmYWN0b3Iodm5vLnNldS5pbnRlZ3JhdGVkJHNldXJhdF9jbHVzdGVycywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzPWFzLmNoYXJhY3RlcigwOjMwKSkKCmBgYAoKCmBgYHtyfQoKSWRlbnRzKHZuby5zZXUuaW50ZWdyYXRlZCkgPC0gdm5vLnNldS5pbnRlZ3JhdGVkJHNldXJhdF9jbHVzdGVycwp2bm8uMmQuY2x1c3Rlci5wY2EgPC0gRGltUGxvdCh2bm8uc2V1LmludGVncmF0ZWQsIHJlZHVjdGlvbj0icGNhIiwgbGFiZWw9VFJVRSwgc2h1ZmZsZT1UUlVFLCByZXBlbD1UUlVFKSArCiAgZ2d0aXRsZSgiVk5PIFBDQSBDbHVzdGVycyIpCgp2bm8uMmQuY2x1c3Rlci5wY2EKCmBgYAoKIyMgM0QgUENBIG9mIENsdXN0ZXJzIAoKYGBge3IgaW5jbHVkZT1GQUxTRX0KCiMgUHJlcGFyZSBhIGRhdGFmcmFtZSBmb3IgY2VsbCBwbG90dGluZy4gVGhlIGxhc3QgY29sdW1uIHdpbGwgZGV0ZXJtaW5lIHRoZSBjb2xvciBvZiB0aGUgZGF0YXBvaW50cy4Kdm5vLjNkLnBjYS5kZiA8LSBGZXRjaERhdGEob2JqZWN0ID0gdm5vLnNldS5pbnRlZ3JhdGVkLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFycyA9IGMoIlBDXzEiLCAiUENfMiIsICJQQ18zIiwgInNldXJhdF9jbHVzdGVycyIpKQoKYGBgCgpgYGB7cn0KCm5Db2xvcnMuY2x1c3RlcnMgPC0gbGVuZ3RoKGxldmVscyh2bm8uM2QucGNhLmRmJHNldXJhdF9jbHVzdGVycykpCnZuby5jbHVzdGVyLmNvbG9ycyA8LSBodWVfcGFsKCkobkNvbG9ycy5jbHVzdGVycykKCmBgYAoKYGBge3IgaW5jbHVkZT1GQUxTRX0KCiMgUGxvdCB5b3VyIGRhdGEKdm5vLjNkLnBjYS5jbHVzdGVyIDwtIHBsb3RfbHkoZGF0YSA9IHZuby4zZC5wY2EuZGYsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ID0gflBDXzEsIHkgPSB+UENfMiwgeiA9IH5QQ18zLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSB+c2V1cmF0X2NsdXN0ZXJzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSA9ICJzY2F0dGVyM2QiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kZSA9ICJtYXJrZXJzIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9ycyA9IHZuby5jbHVzdGVyLmNvbG9ycywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFya2VyID0gbGlzdChzaXplID0gMSwgd2lkdGg9MSksICMgY29udHJvbHMgc2l6ZSBvZiBwb2ludHMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dCA9IH5zZXVyYXRfY2x1c3RlcnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhvdmVyaW5mbz0idGV4dCIpICU+JSBsYXlvdXQodGl0bGU9IlZOTyBQQ0EgQ2x1c3RlcnMiKQoKYGBgCgpgYGB7ciwgZmlnLndpZHRoPTE0LCBmaWcuaGVpZ2h0PTE0fQoKdm5vLjNkLnBjYS5jbHVzdGVyCgpgYGAKCiMjIDJEIFVNQVAgQ2x1c3RlcnMgIAoKYGBge3J9CgpmaWdfMUEgPC0gRGltUGxvdCh2bm8uc2V1LmludGVncmF0ZWQsIHJlZHVjdGlvbiA9ICJ1bWFwIiwgbGFiZWwgPSBUUlVFLCBzaHVmZmxlID0gVFJVRSkgKwogIGdndGl0bGUoIlZOTyBDbHVzdGVycyIpICsgdGhlbWUoYXNwZWN0LnJhdGlvPTEpCgpmaWdfMUEKCmBgYAoKIyMgM0QgVU1BUCBDbHVzdGVycyAgCgpgYGB7ciBpbmNsdWRlPUZBTFNFfQoKRGVmYXVsdEFzc2F5KHZuby5zZXUuaW50ZWdyYXRlZCkgPC0gImludGVncmF0ZWQiCiMgUmUtcnVuIFVNQVAgaW4gNTAgZGltZW5zaW9ucyBhbmQgcmV0YWluIGNhbGN1bGF0aW9ucyBmb3IgdGhlIGZpcnN0IDMgZGltZW5zaW9ucwp2bm8uM2QudW1hcC5zZXUgPC0gUnVuVU1BUCh2bm8uc2V1LmludGVncmF0ZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaW1zID0gMToyNiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG4uY29tcG9uZW50cyA9IDNMKQoKIyBQcmVwYXJlIGEgZGF0YWZyYW1lIGZvciBjZWxsIHBsb3R0aW5nLiBUaGUgbGFzdCBjb2x1bW4gd2lsbCBkZXRlcm1pbmUgdGhlIGNvbG9yIG9mIHRoZSBkYXRhcG9pbnRzLgp2bm8uM2QudW1hcC5kZiA8LSBGZXRjaERhdGEob2JqZWN0PXZuby4zZC51bWFwLnNldSx2YXJzPWMoIlVNQVBfMSIsIlVNQVBfMiIsIlVNQVBfMyIsInNldXJhdF9jbHVzdGVycyIpKQoKcm0odm5vLjNkLnVtYXAuc2V1KTsgaW52aXNpYmxlKGdjKCkpCgpgYGAKCmBgYHtyfQoKbkNvbG9ycy5jbHVzdGVycyA8LSBsZW5ndGgobGV2ZWxzKHZuby4zZC51bWFwLmRmJHNldXJhdF9jbHVzdGVycykpCnZuby5jbHVzdGVyLmNvbG9ycyA8LSBodWVfcGFsKCkobkNvbG9ycy5jbHVzdGVycykKCmBgYAoKYGBge3IgaW5jbHVkZT1GQUxTRX0KCiMgUGxvdCB5b3VyIGRhdGEKdm5vLjNkLnVtYXAuY2x1c3RlciA8LSBwbG90X2x5KGRhdGEgPSB2bm8uM2QudW1hcC5kZiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ID0gflVNQVBfMSwgeSA9IH5VTUFQXzIsIHogPSB+VU1BUF8zLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gfnNldXJhdF9jbHVzdGVycywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlID0gInNjYXR0ZXIzZCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kZSA9ICJtYXJrZXJzIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvcnMgPSB2bm8uY2x1c3Rlci5jb2xvcnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXJrZXIgPSBsaXN0KHNpemUgPSAxLCB3aWR0aD0xKSwgIyBjb250cm9scyBzaXplIG9mIHBvaW50cwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dCA9IH5zZXVyYXRfY2x1c3RlcnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBob3ZlcmluZm89InRleHQiKSAlPiUgbGF5b3V0KHRpdGxlPSJWTk8gVU1BUCBDbHVzdGVycyIpCgpgYGAKCmBgYHtyLCBmaWcud2lkdGg9MTQsIGZpZy5oZWlnaHQ9MTR9Cgp2bm8uM2QudW1hcC5jbHVzdGVyCgpgYGAKCiMjIFVNQVAgdmlzdWFsaXphdGlvbiBvZiBpbnRlZ3JhdGVkIGNlbGwtdHlwZSBjbHVzdGVycyBmb3Igd2hvbGUtVk5PIHNpbmdsZS1jZWxsIFJOQS1zZXEgIAoKYGBge3J9CgpJZGVudHModm5vLnNldS5pbnRlZ3JhdGVkKSA8LSB2bm8uc2V1LmludGVncmF0ZWQkY2VsbF90eXBlCgpgYGAKCj5JbiB0d28tZGltZW5zaW9uYWwgVU1BUCBzcGFjZSwgMTggY2VsbCBjbHVzdGVycyBjYW4gYmUgY2xlYXJseSBpZGVudGlmaWVkLgoKYGBge3IsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD04fQoKZmlnMV9hIDwtIERpbVBsb3Qodm5vLnNldS5pbnRlZ3JhdGVkLCByZWR1Y3Rpb24gPSAidW1hcCIsIGxhYmVsID0gVFJVRSwgc2h1ZmZsZSA9IFRSVUUpICsKICBnZ3RpdGxlKCJWb21lcm9uYXNhbCBPcmdhbiBDZWxsIENsdXN0ZXJzIikgKwogIHRoZW1lKGFzcGVjdC5yYXRpbz0xKQoKc3ZnbGl0ZShmaWxlbmFtZSA9IHBhc3RlMChhZG9iZV9pbWFnZXMsImZpZzFfYS5zdmciKSwgd2lkdGg9MTAsIGhlaWdodD04KQpmaWcxX2EKaW52aXNpYmxlKGRldi5vZmYoKSkKZmlnMV9hCgpgYGAKCiMjIDNEIFVNQVAgQ2VsbC10eXBlcyAgCgpgYGB7ciBpbmNsdWRlPUZBTFNFfQoKRGVmYXVsdEFzc2F5KHZuby5zZXUuaW50ZWdyYXRlZCkgPC0gImludGVncmF0ZWQiCiMgUmUtcnVuIFVNQVAgaW4gNTAgZGltZW5zaW9ucyBhbmQgcmV0YWluIGNhbGN1bGF0aW9ucyBmb3IgdGhlIGZpcnN0IDMgZGltZW5zaW9ucwp2bm8uM2QudW1hcC5zZXUgPC0gUnVuVU1BUCh2bm8uc2V1LmludGVncmF0ZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpbXMgPSAxOjI2LAogICAgICAgICAgICAgICAgICAgICAgICAgICBuLmNvbXBvbmVudHMgPSAzTCkKCiMgUHJlcGFyZSBhIGRhdGFmcmFtZSBmb3IgY2VsbCBwbG90dGluZy4gVGhlIGxhc3QgY29sdW1uIHdpbGwgZGV0ZXJtaW5lIHRoZSBjb2xvciBvZiB0aGUgZGF0YXBvaW50cy4Kdm5vLjNkLnVtYXAuZGYgPC0gRmV0Y2hEYXRhKG9iamVjdD12bm8uM2QudW1hcC5zZXUsdmFycz1jKCJVTUFQXzEiLCJVTUFQXzIiLCJVTUFQXzMiLCJjZWxsX3R5cGUiKSkKCnJtKHZuby4zZC51bWFwLnNldSk7IGludmlzaWJsZShnYygpKQoKYGBgCgpgYGB7cn0KCm5Db2xvcnMuY2x1c3RlcnMgPC0gbGVuZ3RoKGxldmVscyh2bm8uM2QudW1hcC5kZiRjZWxsX3R5cGUpKQp2bm8uY2x1c3Rlci5jb2xvcnMgPC0gaHVlX3BhbCgpKG5Db2xvcnMuY2x1c3RlcnMpCgpgYGAKCmBgYHtyIGluY2x1ZGU9RkFMU0V9CgojIFBsb3QgeW91ciBkYXRhCnZuby4zZC51bWFwLmNsdXN0ZXIgPC0gcGxvdF9seShkYXRhID0gdm5vLjNkLnVtYXAuZGYsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeCA9IH5VTUFQXzEsIHkgPSB+VU1BUF8yLCB6ID0gflVNQVBfMywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IH5jZWxsX3R5cGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSA9ICJzY2F0dGVyM2QiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZGUgPSAibWFya2VycyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3JzID0gdm5vLmNsdXN0ZXIuY29sb3JzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFya2VyID0gbGlzdChzaXplID0gMSwgd2lkdGg9MSksICMgY29udHJvbHMgc2l6ZSBvZiBwb2ludHMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHQgPSB+Y2VsbF90eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaG92ZXJpbmZvPSJ0ZXh0IikgJT4lIGxheW91dCh0aXRsZT0iVk5PIFVNQVAgQ2VsbCBUeXBlcyIpCgpgYGAKCmBgYHtyLCBmaWcud2lkdGg9MTQsIGZpZy5oZWlnaHQ9MTR9Cgp2bm8uM2QudW1hcC5jbHVzdGVyCgpgYGAKCiMjIENlbGwtdHlwZSBtYXJrZXItZ2VuZSBub3JtYWxpemVkIGV4cHJlc3Npb24gYWNyb3NzIHRoZSBjZWxsIGNsdXN0ZXJzICAKCj5UaGVzZSBjbHVzdGVycyB3ZXJlIGN1cmF0ZWQgdXNpbmcga25vd24gY2VsbCBtYXJrZXJzIChGaWcuIDFiKS4KCmBgYHtyLCBpbmNsdWRlPUZBTFNFfQoKIyBPdXIgbWFya2VyIGdlbmVzIHRvIHBsb3QgIApwbG90LmdlbmVzIDwtIGMoIk9tcCIsIkduYWkyIiwiR25nMTMiLCJNZWlzMiIsIkduYW8xIiwiUm9ibzIiLCJUZmFwMmUiLCJHbmFsIiwiQ25nYTIiLCJQMnJ5MTQiLCJYaXN0IiwKICAgICAgICAgICAgICAgICJHYXA0MyIsIlN0bW4yIiwiTmV1cm9nMSIsIk5ldXJvZDEiLCJDY25kMSIsIkFzY2wxIiwiS3J0NSIsIktydDE1IiwiU294OSIsIkhlcGFjYW0yIiwKICAgICAgICAgICAgICAgICJGZXpmMiIsIlNveDIiLCJQbHAxIiwiUzEwMGIiLCJDZGg1IiwiQ2QzNCIsIkFjdGEyIiwiQ29sMWEyIiwiQ3RzcyIsIkRvY2syIiwiQ2QyMDlhIiwKICAgICAgICAgICAgICAgICJTMTAwYTkiLCJUcmJjMiIpCgpgYGAKCgpgYGB7ciwgaW5jdWRlPUZBTFNFfQoKdm5vLnNldS5pbnRlZ3JhdGVkQGFjdGl2ZS5hc3NheSA8LSAiUk5BIgojIEdldCBjZWxsIGV4cHJlc3Npb24gZGF0YSBmb3IgdGhlIGdvaSwgdGhlIGNsdXN0ZXIsIGFuZCB0aGUgY2VsbC10eXBlCnZuby5tYXJrZXJfZ2VuZXMuZGYgPC0gRmV0Y2hEYXRhKG9iamVjdCA9IHZuby5zZXUuaW50ZWdyYXRlZCwgc2xvdD0nZGF0YScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhcnMgPSBjKHBsb3QuZ2VuZXMsICJzZXVyYXRfY2x1c3RlcnMiLCAiY2VsbF90eXBlIikpCnZuby5tYXJrZXJfZ2VuZXMuZGYkQ2VsbCA8LSByb3duYW1lcyh2bm8ubWFya2VyX2dlbmVzLmRmKQoKcGxvdC5nZW5lcyA8LSBwbG90LmdlbmVzW3Bsb3QuZ2VuZXMgJWluJSBjb2xuYW1lcyh2bm8ubWFya2VyX2dlbmVzLmRmKV0KCiMgUmVzaGFwZSB0aGUgZGF0YSBmb3IgcGxvdHRpbmcKdm5vLm1hcmtlcl9nZW5lcy5kZiA8LSByZXNoYXBlMjo6bWVsdCh2bm8ubWFya2VyX2dlbmVzLmRmLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZC52YXJzID0gYygiQ2VsbCIsInNldXJhdF9jbHVzdGVycyIsImNlbGxfdHlwZSIpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZWFzdXJlLnZhcnMgPSBwbG90LmdlbmVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhcmlhYmxlLm5hbWUgPSAiR2VuZSIsIHZhbHVlLm5hbWUgPSAiRXhwciIpCgpgYGAKCgpgYGB7ciwgaW5jbHVkZT1GQUxTRX0KCiMgT3JkZXIgdGhlIGdlbmUgZmFjdG9yIGxldmVscwp2bm8ubWFya2VyX2dlbmVzLmRmJEdlbmUgPC0KICBmYWN0b3Iodm5vLm1hcmtlcl9nZW5lcy5kZiRHZW5lLAogICAgICAgICBsZXZlbHM9YygiT21wIiwiR25haTIiLCJHbmcxMyIsIk1laXMyIiwiR25hbzEiLCJSb2JvMiIsIlRmYXAyZSIsIkduYWwiLCJDbmdhMiIsIlAycnkxNCIsIlhpc3QiLAogICAgICAgICAgICAgICAgIkdhcDQzIiwiU3RtbjIiLCJOZXVyb2cxIiwiTmV1cm9kMSIsIkNjbmQxIiwiQXNjbDEiLCJLcnQ1IiwiS3J0MTUiLCJTb3g5IiwiSGVwYWNhbTIiLAogICAgICAgICAgICAgICAgIkZlemYyIiwiU294MiIsIlBscDEiLCJTMTAwYiIsIkNkaDUiLCJDZDM0IiwiQWN0YTIiLCJDb2wxYTIiLCJDdHNzIiwiRG9jazIiLCJDZDIwOWEiLAogICAgICAgICAgICAgICAgIlMxMDBhOSIsIlRyYmMyIikpCgojIE9yZGVyIHRoZSBzZXVyYXRfY2x1c3RlcnMgZmFjdG9yIGxldmVscwp2bm8ubWFya2VyX2dlbmVzLmRmJHNldXJhdF9jbHVzdGVycyA8LSBmYWN0b3Iodm5vLm1hcmtlcl9nZW5lcy5kZiRzZXVyYXRfY2x1c3RlcnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHM9YygiMCIsIjEiLCIyIiwiMyIsIjEzIiwiMjMiLCI1IiwiMTAiLCIxNSIsIjIxIiwiMjkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiOSIsIjEyIiwiNiIsIjciLCIxOSIsIjI2IiwiMTciLCIyOCIsIjI3IiwiNCIsIjExIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjE4IiwiMzAiLCIyNSIsIjI0IiwiMTYiLCI4IiwiMjAiLCIxNCIsIjIyIikpCgpgYGAKCgpgYGB7ciwgaW5jbHVkZT1GQUxTRX0KCiMgR2V0IG9yZGVyZWQgbGVnZW5kIGRhdGEKbGVnZW5kLmRmIDwtIGRhdGEuZnJhbWUoY2x1c3Rlcj1sZXZlbHModm5vLm1hcmtlcl9nZW5lcy5kZiRzZXVyYXRfY2x1c3RlcnMpLAogICAgICAgICAgICAgICAgICAgICAgICBjZWxsX3R5cGU9YyhyZXAoIlYxUl9tVlNOIiw2KSxyZXAoIlYyUl9tVlNOIiwzKSxyZXAoIm1PU04iLDIpLHJlcCgic1ZTTiIsMiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcCgiVjFSX2lWU04iLDEpLCJWMlJfaVZTTiIsIklOUCIsIkdCQyIscmVwKCJIQkMiLDIpLCJNViIscmVwKCJTVVMiLDQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiT0VDIiwiRW5kb3RoZWxpYWwiLHJlcCgiTFAiLDEpLHJlcCgiTWljcm9nbGlhIiwxKSwiTWljcm9nbGlhX3JwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkltbXVuZV9GcHIiLCJUX2NlbGxzIikpCgpsZWdlbmQuZGYkY2x1c3RlciA8LSBmYWN0b3IobGVnZW5kLmRmJGNsdXN0ZXIsIGxldmVscz1sZXZlbHModm5vLm1hcmtlcl9nZW5lcy5kZiRzZXVyYXRfY2x1c3RlcnMpKQpsZWdlbmQuZGYkY2VsbF90eXBlIDwtIGZhY3RvcihsZWdlbmQuZGYkY2VsbF90eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHM9YygiVjFSX21WU04iLCJWMlJfbVZTTiIsIm1PU04iLCJzVlNOIiwiVjFSX2lWU04iLCJWMlJfaVZTTiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJJTlAiLCJHQkMiLCJIQkMiLCJNViIsIlNVUyIsIk9FQyIsIkVuZG90aGVsaWFsIiwiTFAiLCJNaWNyb2dsaWEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTWljcm9nbGlhX3JwIiwiSW1tdW5lX0ZwciIsIlRfY2VsbHMiKSkKCmBgYAoKCmBgYHtyIGZpZy53aWR0aD0yNSwgZmlnLmhlaWdodD0yMH0KCmZpZzFfYi5wYXJ0MSA8LSBnZ3Bsb3Qodm5vLm1hcmtlcl9nZW5lcy5kZiwgYWVzKHg9c2V1cmF0X2NsdXN0ZXJzLCBFeHByLCBmaWxsPWNlbGxfdHlwZSkpICsKICBnZW9tX3Zpb2xpbihzY2FsZSA9ICJ3aWR0aCIsIGFkanVzdCA9IDEsIHRyaW0gPSBUUlVFKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwgMCksIHBvc2l0aW9uPSJyaWdodCIsIGxhYmVscyA9IGZ1bmN0aW9uKHgpCiAgICAgICAgICAgICAgICAgICAgIGMocmVwKHggPSAiIiwgdGltZXMgPSBsZW5ndGgoeCktMiksIHhbbGVuZ3RoKHgpIC0gMV0sICIiKSkgKwogIGZhY2V0X2dyaWQocm93cyA9IHZhcnMoR2VuZSksIHNjYWxlcyA9ICJmcmVlIiwgc3dpdGNoID0gInkiKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLCBwYW5lbC5zcGFjaW5nID0gdW5pdCgwLCAibGluZXMiKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9NTYsIGZhY2U9ImJvbGQiLCBoanVzdD0wLjcpLAogICAgICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9IE5BLCBjb2xvciA9ICJibGFjayIpLAogICAgICAgIHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgc3RyaXAudGV4dC55LmxlZnQgPSBlbGVtZW50X3RleHQoYW5nbGUgPSAwLCBzaXplPTQwKSwKICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcy54ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemU9NDApLAogICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplPTUwLCB2anVzdD0wLjUpKSArCiAgZ2d0aXRsZSgiVk5PIENlbGwtVHlwZSBNYXJrZXItR2VuZSBOb3JtYWxpemVkIEV4cHJlc3Npb24gYnkgQ2x1c3RlciIpICsgeWxhYigiTm9ybWFsaXplZCBHZW5lIEV4cHJlc3Npb24iKQoKZmlnMV9iLnBhcnQyIDwtIGdncGxvdChsZWdlbmQuZGYsIGFlcyh4ID0gY2x1c3RlciwgeSA9IDEsIGZpbGwgPSBjZWxsX3R5cGUpKSArIAogIGdlb21fdGlsZSh3aWR0aD0wLjk3KSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IHZuby5jZWxsX3R5cGUuY29sb3JzKSArIHNjYWxlX3lfY29udGludW91cyhleHBhbmQgPSBjKDAsIDApKSArCiAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQoZGlyZWN0aW9uID0gInZlcnRpY2FsIiwgbGFiZWwucG9zaXRpb24gPSAicmlnaHQiLAogICAgICAgICAgICAgICAgICAgICAgIHRpdGxlLnRoZW1lID0gZWxlbWVudF9ibGFuaygpLCBrZXloZWlnaHQgPSAwLjUsIG5yb3cgPSAzLCBieXJvdyA9IFRSVUUpKSArCiAgdGhlbWUobGVnZW5kLmtleS5zaXplID0gdW5pdCgyLCAnbGluZXMnKSwKICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChtYXJnaW4gPSBtYXJnaW4ocj0yLCB1bml0PSdwdCcpLCBzaXplPTMwKSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwKICAgICAgICBsZWdlbmQuanVzdGlmaWNhdGlvbiA9ICJjZW50ZXIiLAogICAgICAgIGxlZ2VuZC5tYXJnaW4gPSBtYXJnaW4oMCwwLDAsMCksCiAgICAgICAgbGVnZW5kLmJveC5tYXJnaW4gPSBtYXJnaW4oLTEwLDUsMCwwKSwKICAgICAgICBwYW5lbC5zcGFjaW5nID0gdW5pdCgzLCAibGluZXMiKSwKICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGxvdC5tYXJnaW4gPSBtYXJnaW4oMCwgNywgNywgNywgInB0IiksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjAsIGhqdXN0ID0gMC41LCB2anVzdCA9IDAuNSwgY29sb3IgPSAiYmxhY2siLCBzaXplPTQwKSwKICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZT01MCwgdmp1c3Q9MC41KSwKICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcy55ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF9ibGFuaygpKSArIHhsYWIoIkNsdXN0ZXIiKQoKZmlnMV9iIDwtIHBsb3RfZ3JpZChmaWcxX2IucGFydDEsIGZpZzFfYi5wYXJ0MiwgbmNvbCA9IDEsIHJlbF9oZWlnaHRzID0gYygwLjgzLCAwLjE3KSwgCiAgICAgICAgICAgICAgICAgICAgYWxpZ24gPSAiaHYiLCBheGlzID0gImxyIikKc3ZnbGl0ZShmaWxlbmFtZSA9IHBhc3RlMChhZG9iZV9pbWFnZXMsImZpZzFfYi5zdmciKSx3aWR0aD0yNSwgaGVpZ2h0PTIwKQpmaWcxX2IKaW52aXNpYmxlKGRldi5vZmYoKSkKCmZpZzFfYgoKYGBgCgojIyBVTUFQIG9mIGNlbGwtdHlwZSBjbHVzdGVycyBzcGxpdCBieSBhZ2UgIAoKYGBge3IsIGZpZy53aWR0aD0xNixmaWcuaGVpZ2h0PTh9CgpmaWcxX2MgPC0gRGltUGxvdCh2bm8uc2V1LmludGVncmF0ZWQsIHJlZHVjdGlvbiA9ICJ1bWFwIiwgc2h1ZmZsZSA9IFRSVUUsIHNwbGl0LmJ5ID0gImFnZSIsIG5jb2wgPSAyKSArCiAgdGhlbWVfdm9pZCgpICsgdGhlbWUoYXNwZWN0LnJhdGlvPTEpICsgTm9MZWdlbmQoKQoKc3ZnbGl0ZShmaWxlbmFtZSA9IHBhc3RlMChhZG9iZV9pbWFnZXMsImZpZzFfYy5zdmciKSwgd2lkdGg9MTAsIGhlaWdodD01KQpmaWcxX2MKaW52aXNpYmxlKGRldi5vZmYoKSkKZmlnMV9jCgpgYGAKCiMjIFVNQVAgb2YgY2VsbC10eXBlIGNsdXN0ZXJzIHNwbGl0IGJ5IHNleCAgCgpgYGB7ciwgZmlnLndpZHRoPTE2LGZpZy5oZWlnaHQ9OH0KCmZpZzFfZCA8LSBEaW1QbG90KHZuby5zZXUuaW50ZWdyYXRlZCwgcmVkdWN0aW9uID0gInVtYXAiLCBzaHVmZmxlID0gVFJVRSwgc3BsaXQuYnkgPSAic2V4IiwgbmNvbCA9IDIpICsKICB0aGVtZV92b2lkKCkgKyB0aGVtZShhc3BlY3QucmF0aW89MSkgKyBOb0xlZ2VuZCgpCgpzdmdsaXRlKGZpbGVuYW1lID0gcGFzdGUwKGFkb2JlX2ltYWdlcywiZmlnMV9kLnN2ZyIpLCB3aWR0aD0xMCwgaGVpZ2h0PTUpCmZpZzFfZAppbnZpc2libGUoZGV2Lm9mZigpKQpmaWcxX2QKCmBgYAoKIyMgU3BhdGlhbCBsb2NhdGlvbiBvZiBpbmRpdmlkdWFsIFZOTyBjZWxscyBjb2xvci1jb2RlZCBhY2NvcmRpbmcgdG8gY2VsbCB0eXBlIHByZWRpY3Rpb24gYmFzZWQgb24gdGhlIHNwYXRpYWwgdHJhbnNjcmlwdG9taWMgYW5hbHlzaXMgIAoKYGBge3IsIGV2YWw9RkFMU0V9Cgpsb2FkKGZpbGU9cGFzdGUwKG9iamVjdF9kaXIsInJlc29sdmUuc2V1LlBPU1RwcmVkaWN0IikpCmxvYWQoZmlsZT1wYXN0ZTAob2JqZWN0X2RpciwicmVzb2x2ZS5kYXRhc2V0cy5QT1NUcHJlZGljdCIpKQpsb2FkKGZpbGU9cGFzdGUwKG9iamVjdF9kaXIsInJlc29sdmUucHJlZGljdGlvbnMuYXNzYXkiKSkKCmBgYAoKYGBge3J9CgpyZXNvbHZlLmNlbGwudHlwZXMgPC0gCiAgYXMuZmFjdG9yKHVubGlzdChsYXBwbHkoY29sbmFtZXMocmVzb2x2ZS5wcmVkaWN0aW9ucy5hc3NheSksIGZ1bmN0aW9uKGNlbGwpewogIHJvd25hbWVzKHJlc29sdmUucHJlZGljdGlvbnMuYXNzYXkpW3doaWNoLm1heCh4PXJlc29sdmUucHJlZGljdGlvbnMuYXNzYXlbICxjZWxsXSldCn0pKSkKCmBgYAoKYGBge3J9CgpJZGVudHMocmVzb2x2ZS5zZXUuaW50ZWdyYXRlZCkgPC0gcmVzb2x2ZS5jZWxsLnR5cGVzCmxldmVscyhyZXNvbHZlLnNldS5pbnRlZ3JhdGVkQGFjdGl2ZS5pZGVudClbbGV2ZWxzKHJlc29sdmUuc2V1LmludGVncmF0ZWRAYWN0aXZlLmlkZW50KT09InVua25vd24tbVZTTiJdIDwtICJzVlNOIgoKbGV2ZWxzKHJlc29sdmUuc2V1LmludGVncmF0ZWRAYWN0aXZlLmlkZW50KSA8LSBnc3ViKCItIiwiXyIsIGxldmVscyhyZXNvbHZlLnNldS5pbnRlZ3JhdGVkQGFjdGl2ZS5pZGVudCkpCgpyZXNvbHZlLnNldS5pbnRlZ3JhdGVkQGFjdGl2ZS5pZGVudCA8LQogIGZhY3Rvcihhcy5mYWN0b3IocmVzb2x2ZS5zZXUuaW50ZWdyYXRlZEBhY3RpdmUuaWRlbnQpLCAKICAgICAgICAgbGV2ZWxzID0gYygiVjFSX21WU04iLCJWMlJfbVZTTiIsIm1PU04iLCJzVlNOIiwKICAgICAgICAgICAgICAgICAgICAiVjFSX2lWU04iLCJWMlJfaVZTTiIsIklOUCIsIkdCQyIsIkhCQyIsIk1WIiwKICAgICAgICAgICAgICAgICAgICAiU1VTIiwiT0VDIiwiRW5kb3RoZWxpYWwiLCJMUCIsIk1pY3JvZ2xpYSIsCiAgICAgICAgICAgICAgICAgICAgIk1pY3JvZ2xpYV9ycCIsIkltbXVuZV9GcHIiLCJUX2NlbGxzIikpCgpgYGAKCmBgYHtyfQoKcmVzb2x2ZS5jZWxsX3R5cGUuY29sb3JzIDwtIGh1ZV9wYWwoKShsZW5ndGgobGV2ZWxzKHJlc29sdmUuc2V1LmludGVncmF0ZWRAYWN0aXZlLmlkZW50KSkpCgpuYW1lcyhyZXNvbHZlLmNlbGxfdHlwZS5jb2xvcnMpIDwtIGxldmVscyhyZXNvbHZlLnNldS5pbnRlZ3JhdGVkQGFjdGl2ZS5pZGVudCkKCnJlc29sdmUuY2VsbF90eXBlLmNvbG9yc1siVjFSX21WU04iXSA8LSAiIzAwRkYwMCIgICAjZ3JlZW4KcmVzb2x2ZS5jZWxsX3R5cGUuY29sb3JzWyJWMlJfbVZTTiJdIDwtICIjRkY3RjUwIiAgICNjb3JhbApyZXNvbHZlLmNlbGxfdHlwZS5jb2xvcnNbInNWU04iXSA8LSAiIzhGMDBGRiIgICAgICAgI3Zpb2xldCAKcmVzb2x2ZS5jZWxsX3R5cGUuY29sb3JzWyJMUCJdIDwtICIjMDAwMEZGIiAgICAgICAgICNibHVlICAgCnJlc29sdmUuY2VsbF90eXBlLmNvbG9yc1siU1VTIl0gPC0gIiNGRjAwMDAiICAgICAgICAjcmVkCnJlc29sdmUuY2VsbF90eXBlLmNvbG9yc1siSEJDIl0gPC0gIiNGRkZGMDAiICAgICAgICAjeWVsbG93CnJlc29sdmUuY2VsbF90eXBlLmNvbG9yc1siVjFSX2lWU04iXSA8LSAiI0RGRkYwMCIgICAjY2hhcnRyZXVzZSAKcmVzb2x2ZS5jZWxsX3R5cGUuY29sb3JzWyJWMlJfaVZTTiJdIDwtICIjRkZBNTAwIiAgICNvcmFuZ2UKCmBgYAoKYGBge3J9Cgpjb2xvcnMgPC0gYygiVjFSX21WU04iPSIjNDVCNTAwIiwiVjJSX21WU04iPSIjRTc4NTFFIiwibU9TTiI9IiNEMzkyMDAiLCJzVlNOIj0iIzlDOERGRiIsCiAgICAgICAgICAgICJWMVJfaVZTTiI9IiMwMEMwODciLCJWMlJfaVZTTiI9IiNEMDk0MDAiLCJJTlAiPSIjRkY2MUM3IiwiR0JDIj0iI0VGRkQ1RiIsIAogICAgICAgICAgICAiSEJDIj0iI0ZGRkYwMCIsIk1WIj0iIzAwQzBCMiIsIlNVUyI9IiNGODc2NkQiLCJPRUMiPSIjMDBCQ0Q2IiwKICAgICAgICAgICAgIkVuZG90aGVsaWFsIj0iIzAwQjNGMiIsIkxQIj0iIzI5QTNGRiIsIk1pY3JvZ2xpYSI9IiMwMEJDNTEiLCJNaWNyb2dsaWFfcnAiPSIjRDI3N0ZGIiwKICAgICAgICAgICAgIkltbXVuZV9GcHIiPSIjQjJBMTAwIiwiVF9jZWxscyI9IiNGMTY2RTgiKQoKYGBgCgpgYGB7cn0KCmZpZzFfZi5zYW1wbGVzIDwtIHJlc29sdmUuZGF0YXNldHNbWyJzbGlkZTcuQjJfMiJdXQpjZWxsX25hbWVzIDwtIGNvbG5hbWVzKGZpZzFfZi5zYW1wbGVzKQpjZWxsX3R5cGVzIDwtIHJlc29sdmUuc2V1LmludGVncmF0ZWRAYWN0aXZlLmlkZW50W2NlbGxfbmFtZXNdCmZpZzFfZi5zYW1wbGVzIDwtIEFkZE1ldGFEYXRhKGZpZzFfZi5zYW1wbGVzLCBjZWxsX3R5cGVzLCBjb2wubmFtZT0iY2VsbF90eXBlIikKCmZpZzFfZiA8LSBTcGF0aWFsRGltUGxvdChvYmplY3QgPSBmaWcxX2Yuc2FtcGxlcywgZ3JvdXAuYnkgPSAiY2VsbF90eXBlIiwgcHQuc2l6ZS5mYWN0b3IgPSAyLCBjb2xzID0gY29sb3JzKSArCiAgdGhlbWUoCiAgICBhc3BlY3QucmF0aW8gPSAxLAogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAyNCksCiAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTgpLAogICAgbGVnZW5kLmJveC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiYmx1ZSIsIGNvbG91ciA9ICJ0cmFuc3BhcmVudCIpLAogICAgbGVnZW5kLmtleSA9IGVsZW1lbnRfcmVjdChmaWxsID0gInRyYW5zcGFyZW50IiwgY29sb3VyID0gInRyYW5zcGFyZW50IikKICApICsKICBndWlkZXMoCiAgICBjb2xvciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KHNpemUgPSA1KSkgICMgRW5zdXJlIHRoZSBsZWdlbmQga2V5IHBvaW50cyBhcmUgbGFyZ2VyCiAgKQoKYGBgCgpgYGB7ciwgZmlnLndpZHRoPTEyLCBmaWcuaGVpZ2h0PTEwfQoKc3ZnbGl0ZShmaWxlbmFtZSA9IHBhc3RlMChhZG9iZV9pbWFnZXMsImZpZzFfZi5zdmciKSwgd2lkdGg9MTAsIGhlaWdodD0xMCkKZmlnMV9mIAppbnZpc2libGUoZGV2Lm9mZigpKQpmaWcxX2YKCmBgYAoKIyMgTG9jYXRpb24gb2YgY2VsbCBiZWxvbmdpbmcgdG8gSEJDLCBHQkMsIElOUCwgYW5kIExQIGNlbGwgdHlwZXMsIHJlc3BlY3RpdmVseS4gSGVhdCBpbmRpY2F0ZXMgY29uZmlkZW5jZSBvZiBwcmVkaWN0ZWQgdmFsdWVzICAKCmBgYHtyfQoKYmxhbmtfdGhlbWUgPC0gdGhlbWUocGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gInRyYW5zcGFyZW50IiwgY29sb3VyID0gTkEpLAogICAgICAgICAgICAgICAgICAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJ0cmFuc3BhcmVudCIsIGNvbG91ciA9IE5BKSwKICAgICAgICAgICAgICAgICAgICAgcGFuZWwuZ3JpZCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICAgICAgICAgICAgICAgcGFuZWwuYm9yZGVyID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgICAgICAgICAgICAgICBwbG90Lm1hcmdpbiA9IHVuaXQoYygtMSwgMCwgMCwgMCksICJudWxsIiksCiAgICAgICAgICAgICAgICAgICAgIHBhbmVsLm1hcmdpbiA9IHVuaXQoYygtMSwgMCwgMCwgMCksICJudWxsIiksCiAgICAgICAgICAgICAgICAgICAgIGF4aXMudGl0bGU9ZWxlbWVudF9ibGFuaygpLAogICAgICAgICAgICAgICAgICAgICBheGlzLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9MjApLAogICAgICAgICAgICAgICAgICAgICBwbG90LnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPTMyKSwKICAgICAgICAgICAgICAgICAgICAgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9MTIsYW5nbGU9OTApLAogICAgICAgICAgICAgICAgICAgICBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9MjApLAogICAgICAgICAgICAgICAgICAgICBhc3BlY3QucmF0aW89MSkKCmBgYAoKYGBge3IgaW5jbHVkZT1GQUxTRX0KCmZpZzFfZy5wYXJ0XzEgPC0gU3BhdGlhbEZlYXR1cmVQbG90KGZpZzFfZi5zYW1wbGVzLCBmZWF0dXJlcz1yb3duYW1lcyhyZXNvbHZlLnByZWRpY3Rpb25zLmFzc2F5KVsxMF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB0LnNpemUuZmFjdG9yPTQpICsgYmxhbmtfdGhlbWUgKwogIHNjYWxlX2ZpbGxfZ3JhZGllbnQobG93PSJncmV5ODUiLGhpZ2g9Im1hZ2VudGEiKQoKZmlnMV9nLnBhcnRfMiA8LSBTcGF0aWFsRmVhdHVyZVBsb3QoZmlnMV9mLnNhbXBsZXMsIGZlYXR1cmVzPXJvd25hbWVzKHJlc29sdmUucHJlZGljdGlvbnMuYXNzYXkpWzE3XSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHQuc2l6ZS5mYWN0b3I9NCkgKyBibGFua190aGVtZSArCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3c9ImdyZXk4NSIsaGlnaD0ibWFnZW50YSIpCgpmaWcxX2cucGFydF8zIDwtIFNwYXRpYWxGZWF0dXJlUGxvdChmaWcxX2Yuc2FtcGxlcywgZmVhdHVyZXM9cm93bmFtZXMocmVzb2x2ZS5wcmVkaWN0aW9ucy5hc3NheSlbOF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB0LnNpemUuZmFjdG9yPTQpICsgYmxhbmtfdGhlbWUgKwogIHNjYWxlX2ZpbGxfZ3JhZGllbnQobG93PSJncmV5ODUiLGhpZ2g9Im1hZ2VudGEiKQoKZmlnMV9nLnBhcnRfNCA8LSBTcGF0aWFsRmVhdHVyZVBsb3QoZmlnMV9mLnNhbXBsZXMsIGZlYXR1cmVzPXJvd25hbWVzKHJlc29sdmUucHJlZGljdGlvbnMuYXNzYXkpWzExXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHQuc2l6ZS5mYWN0b3I9NCkgKyBibGFua190aGVtZSArCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3c9ImdyZXk4NSIsaGlnaD0ibWFnZW50YSIpCgoKZmlnMV9nIDwtIGdnYXJyYW5nZShmaWcxX2cucGFydF8xLCBmaWcxX2cucGFydF8yLCBmaWcxX2cucGFydF8zLCBmaWcxX2cucGFydF80LCBuY29sPTQsIG5yb3c9MSkKCmBgYAoKYGBge3IsIGZpZy53aWR0aD0yOCwgZmlnLmhlaWdodD03fQoKc3ZnbGl0ZShmaWxlbmFtZSA9IHBhc3RlMChhZG9iZV9pbWFnZXMsImZpZzFfZy5zdmciKSwgd2lkdGg9MjgsIGhlaWdodD03KQpmaWcxX2cgCmludmlzaWJsZShkZXYub2ZmKCkpCmZpZzFfZwoKYGBgCgoKCgoKCgoKCg==